"""
工具函数模块
包含通用的工具函数
"""
import uuid
import json
import hashlib
import logging
from datetime import datetime, timedelta
from croniter import croniter
from typing import Dict, Any, Optional, List
from .timezone_utils import now as timezone_now


def generate_execution_id() -> str:
    """生成唯一的执行ID"""
    return str(uuid.uuid4())


def generate_task_hash(task_data: Dict[str, Any]) -> str:
    """生成任务的哈希值，用于检测任务变更"""
    task_str = json.dumps(task_data, sort_keys=True)
    return hashlib.md5(task_str.encode()).hexdigest()


def validate_cron_expression(cron_expr: str) -> bool:
    """验证Cron表达式是否有效"""
    try:
        croniter(cron_expr)
        return True
    except (ValueError, TypeError):
        return False


def get_next_run_time(cron_expr: str, base_time: Optional[datetime] = None) -> Optional[datetime]:
    """根据Cron表达式计算下次执行时间"""
    # 获取日志记录器
    logger = logging.getLogger('utils.cron')
    
    logger.debug(f"开始计算下次执行时间，Cron表达式: {cron_expr}")
    try:
        if base_time is None:
            base_time = timezone_now()
            logger.debug(f"使用当前时间作为基准时间: {base_time}")
        else:
            logger.debug(f"使用指定的基准时间: {base_time}")
        
        # 确保base_time是naive datetime（croniter需要）
        if hasattr(base_time, 'tzinfo') and base_time.tzinfo:
            base_time_naive = base_time.replace(tzinfo=None)
            logger.debug(f"将aware datetime转换为naive datetime: {base_time} -> {base_time_naive}")
        else:
            base_time_naive = base_time
            logger.debug(f"base_time已经是naive datetime: {base_time_naive}")
        
        logger.debug(f"创建croniter对象，Cron表达式: {cron_expr}, 基准时间: {base_time_naive}")
        cron = croniter(cron_expr, base_time_naive)
        
        next_time = cron.get_next(datetime)
        logger.debug(f"计算得到的下次执行时间: {next_time}")
        
        # 检查时区信息
        if hasattr(next_time, 'tzinfo') and next_time.tzinfo:
            logger.debug(f"下次执行时间带有时区信息: {next_time.tzinfo}")
        else:
            logger.debug("下次执行时间没有时区信息（naive datetime）")
            
        return next_time
    except (ValueError, TypeError) as e:
        logger.error(f"计算下次执行时间失败: {str(e)}")
        return None


def parse_environment_variables(env_str: Optional[str]) -> Dict[str, str]:
    """解析环境变量字符串"""
    if not env_str:
        return {}
    
    try:
        return json.loads(env_str)
    except (json.JSONDecodeError, TypeError):
        # 尝试解析 KEY=VALUE 格式
        env_vars = {}
        for line in env_str.strip().split('\n'):
            if '=' in line:
                key, value = line.split('=', 1)
                env_vars[key.strip()] = value.strip()
        return env_vars


def parse_dependencies(deps_str: Optional[str]) -> List[str]:
    """解析依赖包字符串"""
    if not deps_str:
        return []
    
    try:
        return json.loads(deps_str)
    except (json.JSONDecodeError, TypeError):
        # 尝试解析每行一个依赖的格式
        return [dep.strip() for dep in deps_str.strip().split('\n') if dep.strip()]


def format_duration(seconds: Optional[float]) -> str:
    """格式化执行时长"""
    if seconds is None:
        return "N/A"
    
    if seconds < 60:
        return f"{seconds:.2f}秒"
    elif seconds < 3600:
        return f"{seconds//60:.0f}分{seconds%60:.0f}秒"
    else:
        hours = seconds // 3600
        minutes = (seconds % 3600) // 60
        return f"{hours:.0f}小时{minutes:.0f}分"


def sanitize_log_output(output: str, max_length: int = 10000) -> str:
    """清理和截断日志输出"""
    if not output:
        return ""
    
    # 移除敏感信息的简单处理
    sanitized = output
    
    # 截断过长的输出
    if len(sanitized) > max_length:
        sanitized = sanitized[:max_length] + "\n... (输出已截断)"
    
    return sanitized


def is_task_overdue(next_run_time: Optional[datetime], tolerance_minutes: int = 5) -> bool:
    """检查任务是否超时未执行"""
    if not next_run_time:
        return False
    
    now = timezone_now()
    tolerance = timedelta(minutes=tolerance_minutes)
    
    return now > (next_run_time + tolerance)


def get_system_info() -> Dict[str, Any]:
    """获取系统信息"""
    import platform
    import psutil
    import time
    
    # 获取内存信息
    memory = psutil.virtual_memory()
    
    # 获取磁盘信息
    disk = psutil.disk_usage('/')
    
    # 获取启动时间
    boot_time = psutil.boot_time()
    
    return {
        'platform': platform.platform(),
        'python_version': platform.python_version(),
        'cpu_count': psutil.cpu_count(),
        'total_memory': memory.total,
        'available_memory': memory.available,
        'memory_percent': memory.percent,
        'cpu_percent': psutil.cpu_percent(interval=1),
        'disk_total': disk.total,
        'disk_used': disk.used,
        'disk_percent': disk.percent,
        'boot_time': boot_time * 1000  # 转换为毫秒时间戳
    }


def create_response(success: bool = True, message: str = "", data: Any = None, 
                   error_code: Optional[str] = None) -> Dict[str, Any]:
    """创建标准的API响应格式"""
    response = {
        'success': success,
        'message': message,
        'timestamp': datetime.utcnow().isoformat()
    }
    
    if data is not None:
        response['data'] = data
    
    if error_code:
        response['error_code'] = error_code
    
    return response